// Copyright 2022 jeff.li. and/or its affiliates.

/*!
 * \file src/ir/functor_common.h
 * \brief Common utils for implementing functors
 */
#pragma once

#include <stddef.h>

#include <tbir/runtime/container.h>

namespace tbir::ir {

// Implementation of Visitors
    template<typename T, typename F>
    inline void VisitArray(const runtime::Array <T> &arr, F fvisit) {
        for (size_t i = 0; i < arr.size(); i++) {
            fvisit(arr[i]);
        }
    }

// Implementation of mutators
    template<typename T, typename F>
    inline runtime::Array <T> MutateArray(const runtime::Array <T> &arr,
                                          F fmutate,
                                          bool allow_copy_on_write = false) {
        if (allow_copy_on_write) {
            // if we allow copy on write, we can directly
            // call the inplace mutate function.
            const_cast<runtime::Array<T> &>(arr).MutateByApply(fmutate);
            return arr;
        } else {
            runtime::Array<T> copy = arr;
            copy.MutateByApply(fmutate);
            return copy;
        }
    }

}  // namespace tbir::ir
